package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.QuanZiApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.dubbo.enums.CommentType;
import com.tanhua.dubbo.pojo.Comment;
import com.tanhua.dubbo.pojo.User;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.pojo.Video;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.VideoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class VideoService {

    @DubboReference(version = "1.0.0")
    private VideoApi videoApi;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    protected FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;




    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @DubboReference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @Autowired
    private VideoMQService videoMQService;


    public Object saveVideo(MultipartFile picFile, MultipartFile videoFile) {
        Long userId = UserThreadLocal.get();

        Video video = new Video();
        video.setUserId(userId);

        //上传图片
        PicUploadResult uploadResult = this.picUploadService.upload(picFile);
        if (StrUtil.isEmpty(uploadResult.getName())) {
            return ErrorResult.builder().errCode("500")
                    .errMessage("上传视频封面图片失败，请重试！").build();
        }

        video.setPicUrl(uploadResult.getName()); //图片

        try {
            //上传小视频
            String fileExtName = StrUtil.subAfter(videoFile.getOriginalFilename(), '.', true);
            StorePath storePath = this.storageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), fileExtName, null);
            video.setVideoUrl(fdfsWebServer.getWebServerUrl() + storePath.getFullPath());
        } catch (Exception e) {
            log.error("上传视频文件失败，userId = {}, file = {}", userId, videoFile.getOriginalFilename(), e);
            return ErrorResult.builder().errCode("501")
                    .errMessage("上传视频文件失败，请重试！").build();
        }

        String videoId = this.videoApi.saveVideo(video);

        //发消息
        this.videoMQService.videoMsg(videoId);
        if (StrUtil.isEmpty(videoId)) {
            return ErrorResult.builder().errCode("502")
                    .errMessage("保存小视频数据失败，请重试！").build();
        }

        return null;
    }

    /**
     * 查询小视频列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryVideoList(Integer page, Integer pageSize) {
        Long userId = UserThreadLocal.get();

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        PageInfo<Video> pageInfo = this.videoApi.queryVideoList(userId, page, pageSize);
        List<Video> records = pageInfo.getRecords();

        if (CollUtil.isEmpty(records)) {
            // TODO 给出默认推荐视频(完成)
            Video video = new Video();
            video.setId(ObjectId.get());
            video.setVid(1L);
            video.setUserId(1L);
            video.setPicUrl("https://liyule.oss-cn-shanghai.aliyuncs.com/images/2021/06/21/7282da89beef98d1438de21844d0a40c.gif");
            video.setVideoUrl("https://liyule.oss-cn-shanghai.aliyuncs.com/images/2021/06/21/1.mp4");
            video.setCreated(System.currentTimeMillis()-3000);
            video.setSeeType(1);
            video.setLongitude("128.178131");
            video.setLatitude("42.184401");
            video.setLocationName("长白山");
            records.add(video);
            //添加数据
            ArrayList<VideoVo> videoVoList= new ArrayList<>();

            VideoVo videoVo = BeanUtil.toBeanIgnoreError(video, VideoVo.class);
            videoVoList.add(videoVo);
            pageResult.setItems(videoVoList);
            return pageResult;
        }

        //查询用户信息
        List<Object> userIds = CollUtil.getFieldValues(records, "userId");
        List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(userIds);

        List<VideoVo> videoVoList = new ArrayList<>();
        for (Video record : records) {
            VideoVo videoVo = new VideoVo();

            videoVo.setUserId(record.getUserId());
            videoVo.setCover(record.getPicUrl());
            videoVo.setVideoUrl(record.getVideoUrl());
            videoVo.setId(record.getId().toHexString());
            videoVo.setSignature("我就是我~"); //TODO 签名

            videoVo.setCommentCount(Convert.toInt(this.quanZiApi.queryCommentCount(videoVo.getId(), CommentType.COMMENT))); //评论数
            videoVo.setHasFocus(this.videoApi.isFollowUser(userId, videoVo.getUserId()) ? 1 : 0); //是否关注
            videoVo.setHasLiked(this.quanZiApi.queryUserIsLike(userId, videoVo.getId()) ? 1 : 0); //是否点赞（1是，0否）
            videoVo.setLikeCount(Convert.toInt(this.quanZiApi.queryLikeCount(videoVo.getId())));//点赞数

            //填充用户信息
            for (UserInfo userInfo : userInfoList) {
                if (ObjectUtil.equals(videoVo.getUserId(), userInfo.getUserId())) {
                    videoVo.setNickname(userInfo.getNickName());
                    videoVo.setAvatar(userInfo.getLogo());
                    break;
                }
            }

            videoVoList.add(videoVo);
        }

        pageResult.setItems(videoVoList);
        return pageResult;
    }
    /**
     * 点赞
     *
     * @param videoId
     * @return
     */
    public Long likeComment(String videoId) {
        Long userId = UserThreadLocal.get();
        Boolean result = this.quanZiApi.likeComment(userId, videoId);
        if (result) {
            return this.quanZiApi.queryCommentCount(videoId);
        }

        return null;
    }

    public Long likeCommentVideo(String videoId) {
        Long userId = UserThreadLocal.get();
        Boolean result = this.quanZiApi.likeCommentVideo(userId, videoId);
        if (result) {
            return this.quanZiApi.queryCommentCount(videoId);
        }
        return null;
    }

    /**
     * 取消点赞
     *
     * @param videoId
     * @return
     */
    public Long disLikeComment(String videoId) {
        Long userId = UserThreadLocal.get();
        Boolean result = this.quanZiApi.disLikeComment(userId, videoId);
        if (result) {
            return this.quanZiApi.queryLikeCount(videoId);
        }
        return null;
    }

    /**
     * 关注用户
     *
     * @param userId
     * @return
     */
    public Boolean followUser(Long userId) {
        Long myId = UserThreadLocal.get();
        return this.videoApi.followUser(myId, userId);
    }

    /**
     * 取消关注
     *
     * @param userId
     * @return
     */
    public Boolean disFollowUser(Long userId) {
        Long myId = UserThreadLocal.get();
        return this.videoApi.disFollowUser(myId, userId);
    }

    public PageResult queryCommentList(String videoId, Integer page, Integer pageSize) {

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();

        //查询评论列表数据
        PageInfo<Comment> pageInfo = this.quanZiApi.queryCommentList(videoId, page, pageSize);
        List<Comment> records = pageInfo.getRecords();
        if(CollUtil.isEmpty(records)){
            return pageResult;
        }

        //查询用户信息
        List<Object> userIdList = CollUtil.getFieldValues(records, "userId");
        List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(userIdList);

        List<CommentVo> result = new ArrayList<>();
        for (Comment record : records) {
            CommentVo commentVo = new CommentVo();
            commentVo.setContent(record.getContent());
            commentVo.setId(record.getId().toHexString());
            commentVo.setCreateDate(DateUtil.format(new Date(record.getCreated()), "HH:mm"));
            //是否点赞
            commentVo.setHasLiked(this.quanZiApi.queryUserIsLikeVideo(userId, commentVo.getId()) ? 1 : 0);
            //点赞数
            commentVo.setLikeCount(Convert.toInt(this.quanZiApi.queryCommentCountVideo(commentVo.getId())));

            for (UserInfo userInfo : userInfoList) {
                if(ObjectUtil.equals(record.getUserId(), userInfo.getUserId())){
                    commentVo.setAvatar(userInfo.getLogo());
                    commentVo.setNickname(userInfo.getNickName());
                    break;
                }
            }
            result.add(commentVo);
        }
        pageResult.setItems(result);
        return pageResult;
    }


    public Boolean saveComment(String videoId, String content) {

        return this.quanZiApi.saveComment(UserThreadLocal.get(), videoId, content);
    }
}

